package fons.navigator.views.river;

import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import edu.umd.cs.piccolo.PCamera;
import edu.umd.cs.piccolo.PNode;
import edu.umd.cs.piccolo.event.PBasicInputEventHandler;
import edu.umd.cs.piccolo.event.PInputEvent;
import edu.umd.cs.piccolo.event.PPanEventHandler;
import edu.umd.cs.piccolo.nodes.PPath;
import edu.umd.cs.piccolo.util.PBounds;
import edu.umd.cs.piccolo.util.PDimension;
import fons.navigator.util.GeomUtils;

public class OptionOverlay extends PPath {
	private static final long serialVersionUID = 1L;
	
	private final VisualRiver visualRiver;
	private final PCamera camera;
	private final PropertyChangeListener boundsListener;
	
	private PPath overlay;
	private PNode node;
		
	public OptionOverlay (VisualRiver river, PCamera cam) {
		this.visualRiver = river;
		this.camera = cam;
		this.overlay = new PPath();
		this.overlay.setPaint(new Color(0.5f, 0.5f, 0.5f, 0.5f));
		this.overlay.setStroke(null);
		this.addChild(overlay);
		
		this.boundsListener = new PropertyChangeListener() {
			
			@Override
			public void propertyChange(PropertyChangeEvent evt) {
				if (evt.getPropertyName() == PCamera.PROPERTY_BOUNDS) {
					OptionOverlay.this.update();
				} else if (evt.getPropertyName() == PCamera.PROPERTY_VIEW_TRANSFORM) {
					OptionOverlay.this.update();
				}
			}
		};
		
		this.overlay.addInputEventListener(new PBasicInputEventHandler() {
			private PPanEventHandler panEventHandler;
						
			@Override
			public void mousePressed(PInputEvent event) {
				panEventHandler = visualRiver.getRiverView().getVisualCanvas().getPanEventHandler();
				visualRiver.getRiverView().getVisualCanvas().setPanEventHandler(null);
			}
			
			@Override
			public void mouseDragged(PInputEvent event) {			
				if (event.isRightMouseButton()) {
					PDimension dim = event.getDelta();
					Stream stream = (Stream) node;
					stream.setValueSpacing((float) (stream.getValueSpacing() * (1+dim.width/node.getWidth())));
					stream.setValueScale((float) (stream.getValueScale() * (1-dim.height/node.getHeight())));
					stream.redraw();
					update();
					
				} else if (event.isLeftMouseButton()) {
					PDimension dim = event.getDelta();
					Stream stream = (Stream) node;
					stream.translate(dim.getWidth(), dim.getHeight());
					
					camera.viewToLocal(dim);
					overlay.translate(dim.getWidth(), dim.getHeight());
				}
			}
			
			@Override
			public void mouseReleased(PInputEvent event) {
				visualRiver.getRiverView().getVisualCanvas().setPanEventHandler(panEventHandler);
			}
		});
	}
	
	private void update () {
		PBounds bounds = node.getFullBounds();
		camera.viewToLocal(bounds);
		GeomUtils.growRectInPlace(bounds, 10, 10, 42, 10);
		this.overlay.setPathTo(new Rectangle2D.Double(0, 0, bounds.width, bounds.height));
		this.overlay.setOffset(bounds.x, bounds.y);
	}
	
	public static void addTo (final PNode node, final OptionOverlay overlay) {
		overlay.node = node;
		
		overlay.addInputEventListener(new PBasicInputEventHandler() {
			@Override
			public void mouseExited(PInputEvent event) {
				overlay.remove();
			}
			
			@Override
			public void mouseClicked(PInputEvent event) {
				if (event.isRightMouseButton())
					overlay.remove();
			}
		});
		
		node.addInputEventListener(new PBasicInputEventHandler() {
			@Override
			public void mouseClicked(PInputEvent event) {
				if (event.isLeftMouseButton()) {
					overlay.show();
				}
			}
		});
	}
	
	private boolean added = false;

	protected void remove() {
		if (added == false) return;
		camera.removePropertyChangeListener(boundsListener);
		camera.removeChild(this);
		added = false;
	}

	protected void show() {
		if (added == true) return;
		camera.addPropertyChangeListener(boundsListener);
		camera.addChild(this);
		update();
		added = true;
	}
}
